<script setup lang="ts">
import { ref, watch, onMounted } from "vue"
type MessageType = 'success' | 'warning' | 'error' | 'none'

interface MessageProps {
    tips?: string,
    type?: MessageType,
    visible?: boolean,
    duration?: number,
    id?: string;
    size?: string;
    color?: string;
}

const props = withDefaults(defineProps<MessageProps>(), {
    tips: '',
    type: 'success',
    visible: false,
    duration: 1500,
    id: 'oc-message',
    size: "32px",
    color: '#fff'
})

const state = ref(false)
const title = ref(props.tips)
const status = ref(props.type)
const lock = ref(false)
const timer1 = ref<NodeJS.Timeout | null>()
const timer2 = ref<NodeJS.Timeout | null>()
const size = ref(props.size)
const color = ref(props.color)

watch(() => props.visible, (val: boolean) => {
    state.value = val
    show()
})

const hide = async () => {
    timer1.value = await setTimeout(() => {
        lock.value = false
    }, props.duration - 300)
    await setTimeout(() => {
        state.value = false
    }, props.duration - 200)
    timer2.value = setTimeout(() => {
        document.body.removeChild(document.querySelector('#' + props.id) as Node)
    }, props.duration - 100)
}

const show = () => {
    if (state.value) {
        return
    }

    clearTimeout(timer1.value as NodeJS.Timeout)
    clearTimeout(timer2.value as NodeJS.Timeout)

    state.value = true
    lock.value = true

    hide()
}

onMounted(() => show())

</script>

<template>
    <div v-if="state" :class="['oc-message-wrap zoomIn', !lock ? 'zoomOut' : '']">
        <div class="oc-message-box" :style="{ fontSize: size, color: color }">
            <!-- 成功 -->
            <svg v-if="status === 'success'" xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 28 28"
                fill="none">
                <path d="M7 14.413L8.413 13L12 16.586L19.585 9L21 10.415L12 19.414L7 14.413Z" fill="white" />
                <path
                    d="M6.22202 2.35943C8.52431 0.821086 11.2311 0 14 0C17.713 0 21.274 1.475 23.8995 4.1005C26.525 6.72601 28 10.287 28 14C28 16.7689 27.1789 19.4757 25.6406 21.778C24.1022 24.0803 21.9157 25.8747 19.3576 26.9343C16.7994 27.9939 13.9845 28.2712 11.2687 27.731C8.55301 27.1908 6.05845 25.8574 4.10051 23.8995C2.14258 21.9416 0.809205 19.447 0.269012 16.7313C-0.271181 14.0155 0.00606596 11.2006 1.06569 8.64243C2.12532 6.08427 3.91973 3.89777 6.22202 2.35943ZM7.33316 23.9776C9.30655 25.2962 11.6266 26 14 26C17.1826 26 20.2348 24.7357 22.4853 22.4853C24.7357 20.2348 26 17.1826 26 14C26 11.6266 25.2962 9.30655 23.9776 7.33316C22.6591 5.35977 20.7849 3.8217 18.5922 2.91345C16.3995 2.00519 13.9867 1.76755 11.6589 2.23058C9.33115 2.6936 7.19296 3.83649 5.51472 5.51472C3.83649 7.19295 2.69361 9.33114 2.23058 11.6589C1.76756 13.9867 2.0052 16.3995 2.91345 18.5922C3.8217 20.7849 5.35977 22.6591 7.33316 23.9776Z"
                    fill="white" />
            </svg>
            <!-- 错误 -->
            <svg t="1701830058780" v-else-if="status === 'error'" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
                p-id="1955" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
                <path d="M0 0h1024v1024H0z" fill="none" p-id="1956"></path>
                <path
                    d="M512 80C273.794 80 80 273.794 80 512s193.794 432 432 432 432-193.794 432-432S750.206 80 512 80m0-80c282.77 0 512 229.23 512 512S794.77 1024 512 1024 0 794.77 0 512 229.23 0 512 0z"
                    fill="#fff" p-id="1957"></path>
                <path d="M427.146 370.58L653.42 596.85a40 40 0 0 1-56.568 56.568L370.578 427.146a40 40 0 0 1 56.568-56.568z"
                    fill="#fff" p-id="1958"></path>
                <path d="M653.42 427.146L427.15 653.42a40 40 0 0 1-56.568-56.568l226.274-226.274a40 40 0 0 1 56.568 56.568z"
                    fill="#fff" p-id="1959"></path>
            </svg>
            <!-- 警告 -->
            <svg :width="size" :height="size" v-else-if="status === 'warning'" viewBox="0 0 48 48" fill="none"
                xmlns="http://www.w3.org/2000/svg">
                <path fill-rule="evenodd" clip-rule="evenodd" d="M24 5L2 43H46L24 5Z" fill="none" :stroke="color"
                    stroke-width="4" stroke-linejoin="round" />
                <path d="M24 35V36" :stroke="color" stroke-width="4" stroke-linecap="round" />
                <path d="M24 19.0005L24.0083 29" :stroke="color" stroke-width="4" stroke-linecap="round" />
            </svg>

            <span :class="[status === 'none' ? '' : 'oc-message-text']">{{ title }}</span>
        </div>
    </div>
</template>

<style scoped lang="scss">
.oc-message-wrap {
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    margin: auto;
    user-select: none;
    z-index: 9999;

    .oc-message-box {
        box-shadow: 0 0 10px var(--border-1);
        border: 1px solid var(--border-1);
        padding: var(--space-15);
        display: flex;
        align-items: center;
        flex-direction: column;
        border-radius: var(--border-radius);
        background-color: rgba(0, 0, 0, .7);
        color: #fff;
        padding: 26px 11px;
        width: 120px;
        // height: 29.3333vw;
        border-radius: 10px;
        svg{
            width: 30px;
            height: 30px;
        }
        .oc-message-text {
            // margin-left:8px
            margin-top: 10px;
            white-space: nowrap;
        }
    }
}

.zoomIn {
    animation: zoomIn 0.15s linear;
}

.zoomOut {
    animation: zoomOut 0.15s linear;
}

@keyframes zoomIn {
    0% {
        opacity: 0;
        transform: scale(0);
    }

    30% {
        opacity: 0.3;
        transform: scale(0.3)
    }

    60% {
        opacity: 0.6;
        transform: scale(0.6)
    }

    100% {
        opacity: 1;
        transform: scale(1);
    }
}

@keyframes zoomOut {
    0% {
        opacity: 1;
        transform: scale(1);
    }

    30% {
        opacity: 0.6;
        transform: scale(0.6)
    }

    60% {
        opacity: 0.3;
        transform: scale(0.3)
    }

    100% {
        opacity: 0;
        transform: scale(0);
    }
}
</style>